package sample;

import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;

import java.math.BigDecimal;
import java.sql.*;
import java.util.Date;
import java.util.ResourceBundle;

public class ChangeListenerDemo implements ChangeListener {

	WebEngine webEngine = null;
	Stage stage = null;
	String pageHome = "";

	ChangeListenerDemo(){

	}

	ChangeListenerDemo(WebEngine webEngine, Stage stage){
		this.webEngine = webEngine;
		this.stage = stage;
	}




	@Override
	public void changed(ObservableValue observable, Object oldValue, Object newState) {

		System.gc();

		Connection conn = initializeDB();
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		Statement stmt = null;

		if (newState != Worker.State.SUCCEEDED)
			return;


		// 改变程序标题名称
		stage.setTitle(webEngine.getLocation());


		// 当监听的网站url中不包含"tradeListQuery"，说明用户没有进入对帐中心
		if (webEngine.getLocation().indexOf("tradeListQuery") >= 0){
			// 新版本
			newVersion(conn, preparedStatement, resultSet, stmt);
		} else if (webEngine.getLocation().indexOf("record/standard.htm") >= 0){
			// 支付宝标准版
			standard(conn, preparedStatement, resultSet, stmt);
		}
	}

	// 支付宝标准版 https://consumeprod.alipay.com/record/standard.htm
	private void standard(Connection conn, PreparedStatement preparedStatement, ResultSet resultSet, Statement stmt){

		//今日的20笔交易号
		String toDayTransactionNumberStr = (String) webEngine.executeScript("function aa(){var tradeRecordsIndex=document.getElementById(\"tradeRecordsIndex\");var tbody=tradeRecordsIndex.getElementsByTagName('tbody');var trs=tbody[0].getElementsByTagName('tr');var roders=[];for(var i in trs){if(!trs.hasOwnProperty(i))continue;var tr=trs[i];var tds=tr.getElementsByTagName('td');var ps=tds[1].innerText.split(/\\n\\s*/g);var date=ps[0];var toDate=new Date();if(date=='今天')date=toDate.getFullYear()+'-'+(toDate.getMonth()+1)+'-'+toDate.getDate();if(date=='昨天')date=toDate.getFullYear()+'-'+(toDate.getMonth()+1)+'-'+(toDate.getDate()-1);date+=' '+ps[1]+':00';var name_p=tds[2].getElementsByTagName('p');var remark=name_p[0].innerText;var name=name_p[1].innerText.replace(/\\|\\s*/g,'').replace(/\\s*/g,'');var tradeNo=tds[2].getElementsByClassName('J-tradeNo')[0].title;var amount_td=tds[3].getElementsByClassName('amount-pay')[0].innerText.split(/\\s/g);var amount=amount_td[1];var amount_type=amount_td[0];var status=tds[5].getElementsByClassName('text-muted')[0].innerText;var item=tradeNo+'|'+date+\"|\"+amount+'|'+remark+'|'+name+'|'+amount_type;if(amount_type=='+')roders.push(item)}return roders.toString()}aa();");

//		System.out.println(toDayTransactionNumberStr);
		if (checkNumberStr(conn, toDayTransactionNumberStr)) return;

		String date = DateUtils.formatDate(new Date(), "yyyy-MM-dd hh:mm:ss");

		if (toDayTransactionNumberStr.length() < 1){
			System.out.println(date + ":\t无任何交易");
			try {
				if (StringUtil.isNotEmpty(conn))
					conn.close();
			} catch (Exception e){
				e.printStackTrace();
			}
			webEngine.executeScript("setTimeout(function(){location.reload()},1000*10)");
			return;
		}

		String[] ToDay_Number = toDayTransactionNumberStr.split(",");

		try {

			System.out.println(date);
			for (String number: ToDay_Number){

				// 下面打印下每一笔订单[订单号|时间|金额|备注]
				System.out.println(number);

				String[] row = number.split("\\|");

				if (row.length < 2){
					System.out.println("该长度小于2，跳出本次循环");
					continue;
				}



//				System.out.println(row[row.length-1]);
				String sql ="select id,account,name,state,phone,t.balance,t.topUpProportion from t_s_user t where account = ?";//问号作为参数的占位符
				String account = row[3];


				preparedStatement = conn.prepareStatement(sql);
				preparedStatement.setString(1, account);
				resultSet = preparedStatement.executeQuery();
				TSUser user = new TSUser();
				while (resultSet.next()){
					user.setId(resultSet.getInt("id"));
					user.setAccount(resultSet.getString("account"));
					user.setName(resultSet.getString("name"));
					user.setState(resultSet.getInt("state"));
					user.setBalance(resultSet.getDouble("balance"));
					user.setTopUpProportion(resultSet.getDouble("topUpProportion"));
				}

//						System.out.println(user.toString());
//						System.out.println("记录数：" + resultSet.getRow());
				resultSet.last();


				//先查该订单是否存在
				sql ="select count(id) 'total' from ft_taobaoNumber where number=?";//问号作为参数的占位符
				if (!StringUtil.isNotEmpty(conn)){
					conn = initializeDB();
					System.out.println("数据库连接被断开，重新连接");
				}

				if (!StringUtil.isNotEmpty(row[0]) || row[0].length() < 1){
					System.out.println("当【流水号】异常时，路过本次循环");
					continue;
				}

				// System.out.println("account:\t" + row[0]);

				preparedStatement = conn.prepareStatement(sql);
				preparedStatement.setString(1, row[0]);
				resultSet = preparedStatement.executeQuery();
				while (resultSet.next()){
					if (resultSet.getInt("total") < 1){
						String queryString = "insert into ft_taobaoNumber (number,createTime,price,status,remark) value (?,?,?,?,?)";//问号作为参数的占位符
						preparedStatement = conn.prepareStatement(queryString);

						preparedStatement.setString(1, row[0]);
						preparedStatement.setString(2, row[1]);
						preparedStatement.setString(3, row[2]);
						preparedStatement.setInt(4, 0);
						preparedStatement.setString(5, account);
						preparedStatement.execute();// 插入淘宝交易号

						// 当用户输入的“备注”不存在，或者错误时，不进行自己充值
						if (!StringUtil.isNotEmpty(user.getAccount()))
							continue;

						//当用户输入的充值描述准确时
						//插入充值记录
						if (resultSet.getRow() > 0){
							queryString = "insert into ffp_records_consumption (orderId,consumptionType,note,remark,number,consumptionPrev,consumptionNext,integralChange,createTime,consumptionStatus) values (?,?,?,?,?,?,?,?,now(),?)";//问号作为参数的占位符

							// 充值后余额
							Double balanceNext = new BigDecimal(user.getBalance().doubleValue()).add(new BigDecimal(Double.parseDouble(row[2]))).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
							Double topUpProportion = new BigDecimal(user.getTopUpProportion()).multiply(new BigDecimal(Double.parseDouble(row[2]))).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

							preparedStatement = conn.prepareStatement(queryString);
							preparedStatement.setString(1, row[0]);	// orderId
							preparedStatement.setInt(2, 1);		// type
							preparedStatement.setString(3, "自动充值");	// note
							preparedStatement.setString(4, "自动充值");	// remark
							preparedStatement.setInt(5, -1);		// number
							preparedStatement.setDouble(6, user.getBalance());	// consumptionPrev
							preparedStatement.setDouble(7, balanceNext);	// consumptionNext
							preparedStatement.setDouble(8, topUpProportion);	// topUpProportion
							preparedStatement.setInt(9, 1);	// status
							int flag = preparedStatement.executeUpdate();//执行查询语句
							//System.out.println("充值订单，是否插入成功：" + flag);


							Integer id = 0;
							queryString = "select rc.id from ffp_records_consumption rc where rc.orderId=?";//问号作为参数的占位符
							preparedStatement = conn.prepareStatement(queryString);
							preparedStatement.setString(1, row[0]);	// orderId
							ResultSet resultId = preparedStatement.executeQuery();
							while (resultId.next()){
								id = resultId.getInt("id");
							}

							queryString = "insert into ffp_records_consumption_user (records_consumption_id,user_id) values (?,?)";//问号作为参数的占位符
							preparedStatement = conn.prepareStatement(queryString);
							preparedStatement.setInt(1, id);				// records_consumption_id
							preparedStatement.setInt(2, user.getId());	// user_id
							flag = preparedStatement.executeUpdate();//执行查询语句
							//System.out.println("充值订单->用户，是否插入成功：" + flag);


							queryString = "update t_s_user set balance=? where id=?";//问号作为参数的占位符
							preparedStatement = conn.prepareStatement(queryString);
							preparedStatement.setDouble(1, balanceNext);	// 充值后余额
							preparedStatement.setInt(2, user.getId());	// user_id
							flag = preparedStatement.executeUpdate();//执行查询语句
							//System.out.println("修改用户余额，是否成功：" + flag);

							queryString = "update ft_taobaoNumber set status=? where number=?";//问号作为参数的占位符
							preparedStatement = conn.prepareStatement(queryString);
							preparedStatement.setDouble(1, 1);		// status
							preparedStatement.setString(2, row[0]);	// 淘宝交易编号
							flag = preparedStatement.executeUpdate();//执行查询语句
							//System.out.println("修改交易号为已使用，是否成功：" + flag);



							HttpUtil hu = new HttpUtil();
							hu.sendGet(pageHome + "/api/topUpController/autoTopUpCallBack", "account=" + user.getAccount(), "utf-8");

							hu = null;
							id = null;
							balanceNext = null;
							topUpProportion = null;
						}

						queryString = null;
					}


				}
				sql = null;
				user = null;


			}

			// 加上一个回车
			System.out.println();

			if (StringUtil.isNotEmpty(resultSet))
				resultSet.close();
			if (StringUtil.isNotEmpty(conn))
				conn.close();
			if (StringUtil.isNotEmpty(preparedStatement))
				preparedStatement.close();




		} catch (SQLException ex) {
			ex.printStackTrace();
		} finally {
			try{
				if (StringUtil.isNotEmpty(resultSet))
					resultSet.close();
				if (StringUtil.isNotEmpty(conn))
					conn.close();
				if (StringUtil.isNotEmpty(preparedStatement))
					preparedStatement.close();
			} catch (Exception e){
				e.printStackTrace();
			}
		}

		toDayTransactionNumberStr = null;
		ToDay_Number = null;

		webEngine.executeScript("setTimeout(function(){location.reload()},1000*10)");
		System.gc();

		Worker<Void> worker = webEngine.getLoadWorker();
		ReadOnlyObjectProperty<Worker.State> objectProperty = worker.stateProperty();
		objectProperty.removeListener(this);
		objectProperty.addListener(this);

	}

	private boolean checkNumberStr(Connection conn, String toDayTransactionNumberStr) {
		if (null == toDayTransactionNumberStr) {
			try {
				System.out.println("抓取失败，重新刷新监听网站");
				if (StringUtil.isNotEmpty(conn))
					conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			webEngine.executeScript("location.href = location.href;");
			return true;
		}
		return false;
	}

	private void newVersion(Connection conn, PreparedStatement preparedStatement, ResultSet resultSet, Statement stmt){
		// 执行下面函数，模拟用户点击只看，成功订单
		webEngine.executeScript("function getAnimated(){var _1 = document.querySelectorAll('div[aria-selected][role=\"tab\"][aria-disabled=\"false\"].ant-tabs-tab');for(var i in _1)if(i==6)return _1[i].click();}getAnimated()");


		//今日的20笔交易号
		String toDayTransactionNumberStr = (String) webEngine.executeScript(
				"function aa(){" +
						//"function sleep(n) {var start = new Date().getTime();while(true)  if(new Date().getTime()-start > n) break;}" +
						"var displayText = document.getElementsByClassName('displayText___R2YtL');" +
						"var str = [];" +
						"for(var i in displayText){" +
						"try{" +
						"if (displayText[i].getAttribute('data-clipboard-text') && displayText[i].title.length > 24){" +



						"var wrapper_QonTy = displayText[i].parentNode;" +
						"var wrapper_QonTy_p_div = wrapper_QonTy.parentNode;" +
						"var jiaoyihao_td = wrapper_QonTy_p_div.parentNode;" +

						"var name_td = jiaoyihao_td.previousSibling;" +
						"var time_td = name_td.previousSibling;" +

						"var phone_td = jiaoyihao_td.nextSibling;" +
						"var price_tr = phone_td.nextSibling;" +

						"var tuikuan_td = price_tr.nextSibling;" +
						"var fuwu_td = tuikuan_td.nextSibling;" +
						"var status_td = fuwu_td.nextSibling;" +

						"if (status_td.innerText.trim() != '成功')continue;" +

						"var li = displayText[i].title;" +
						"li +=  '|' + time_td.innerText.trim();" +
						"li += '|' + price_tr.innerText.trim();" +
						"li += '|' + name_td.firstChild.firstChild.innerText;" +


						"str.push(li.replace(/\\n/g,' '));" +
						"}" +

						"}catch(e){" +
						"console.log('error')" +
						"}" +
						"}" +
						"return str.toString();" +
						"}" +
						"aa()"
		);

		//System.out.println(toDayTransactionNumberStr);
		if (checkNumberStr(conn, toDayTransactionNumberStr)) return;

		String date = DateUtils.formatDate(new Date(), "yyyy-MM-dd hh:mm:ss");
		if (toDayTransactionNumberStr.length() < 1){
			System.out.println(date + ":\t无任何交易");
			try {
				if (StringUtil.isNotEmpty(conn))
					conn.close();
			} catch (Exception e){
				e.printStackTrace();
			}
			webEngine.executeScript("setTimeout(function(){location.reload()},1000*10)");
			return;
		}

		String[] ToDay_Number = toDayTransactionNumberStr.split(",");

		try {

			System.out.println(date);
			for (String number: ToDay_Number){

				// 下面打印下每一笔订单[订单号|时间|金额|备注]
				System.out.println(number);

				String[] row = number.split("\\|");

				if (row.length < 2){
					System.out.println("该长度小于2，跳出本次循环");
					continue;
				}



//						System.out.println(row[row.length-1]);

				String sql ="select id,account,name,state,phone,t.balance,t.topUpProportion from t_s_user t where account = ?";//问号作为参数的占位符
				String account = row[row.length-1];
				if (account.indexOf("商品-") >= 0)
					account = account.substring(3);

				preparedStatement = conn.prepareStatement(sql);
				preparedStatement.setString(1, account);
				resultSet = preparedStatement.executeQuery();
				TSUser user = new TSUser();
				while (resultSet.next()){
					user.setId(resultSet.getInt("id"));
					user.setAccount(resultSet.getString("account"));
					user.setName(resultSet.getString("name"));
					user.setState(resultSet.getInt("state"));
					user.setBalance(resultSet.getDouble("balance"));
					user.setTopUpProportion(resultSet.getDouble("topUpProportion"));
				}

//						System.out.println(user.toString());
//						System.out.println("记录数：" + resultSet.getRow());
				resultSet.last();


				//先查该订单是否存在
				sql ="select count(id) 'total' from ft_taobaoNumber where number=?";//问号作为参数的占位符
				if (!StringUtil.isNotEmpty(conn)){
					conn = initializeDB();
					System.out.println("数据库连接被断开，重新连接");
				}

				if (!StringUtil.isNotEmpty(row[0]) || row[0].length() < 1){
					System.out.println("当【流水号】异常时，路过本次循环");
					continue;
				}

				// System.out.println("account:\t" + row[0]);

				preparedStatement = conn.prepareStatement(sql);
				preparedStatement.setString(1, row[0]);
				resultSet = preparedStatement.executeQuery();
				while (resultSet.next()){
					if (resultSet.getInt("total") < 1){
						String queryString = "insert into ft_taobaoNumber (number,createTime,price,status,remark) value (?,?,?,?,?)";//问号作为参数的占位符
						preparedStatement = conn.prepareStatement(queryString);

						preparedStatement.setString(1, row[0]);
						preparedStatement.setString(2, row[1]);
						preparedStatement.setString(3, row[2]);
						preparedStatement.setInt(4, 0);
						preparedStatement.setString(5, row[3]==null?"":row[3]);
						preparedStatement.execute();// 插入淘宝交易号

						// 当用户输入的“备注”不存在，或者错误时，不进行自己充值
						if (!StringUtil.isNotEmpty(user.getAccount()))
							continue;

						//当用户输入的充值描述准确时
						//插入充值记录
						if (resultSet.getRow() > 0){
							queryString = "insert into ffp_records_consumption (orderId,consumptionType,note,remark,number,consumptionPrev,consumptionNext,integralChange,createTime,consumptionStatus) values (?,?,?,?,?,?,?,?,now(),?)";//问号作为参数的占位符

							// 充值后余额
							Double balanceNext = new BigDecimal(user.getBalance().doubleValue()).add(new BigDecimal(Double.parseDouble(row[2]))).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
							Double topUpProportion = new BigDecimal(user.getTopUpProportion()).multiply(new BigDecimal(Double.parseDouble(row[2]))).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

							preparedStatement = conn.prepareStatement(queryString);
							preparedStatement.setString(1, row[0]);	// orderId
							preparedStatement.setInt(2, 1);		// type
							preparedStatement.setString(3, "自动充值");	// note
							preparedStatement.setString(4, "自动充值");	// remark
							preparedStatement.setInt(5, -1);		// number
							preparedStatement.setDouble(6, user.getBalance());	// consumptionPrev
							preparedStatement.setDouble(7, balanceNext);	// consumptionNext
							preparedStatement.setDouble(8, topUpProportion);	// topUpProportion
							preparedStatement.setInt(9, 1);	// status
							int flag = preparedStatement.executeUpdate();//执行查询语句
							//System.out.println("充值订单，是否插入成功：" + flag);


							Integer id = 0;
							queryString = "select rc.id from ffp_records_consumption rc where rc.orderId=?";//问号作为参数的占位符
							preparedStatement = conn.prepareStatement(queryString);
							preparedStatement.setString(1, row[0]);	// orderId
							ResultSet resultId = preparedStatement.executeQuery();
							while (resultId.next()){
								id = resultId.getInt("id");
							}

							queryString = "insert into ffp_records_consumption_user (records_consumption_id,user_id) values (?,?)";//问号作为参数的占位符
							preparedStatement = conn.prepareStatement(queryString);
							preparedStatement.setInt(1, id);				// records_consumption_id
							preparedStatement.setInt(2, user.getId());	// user_id
							flag = preparedStatement.executeUpdate();//执行查询语句
							//System.out.println("充值订单->用户，是否插入成功：" + flag);


							queryString = "update t_s_user set balance=? where id=?";//问号作为参数的占位符
							preparedStatement = conn.prepareStatement(queryString);
							preparedStatement.setDouble(1, balanceNext);	// 充值后余额
							preparedStatement.setInt(2, user.getId());	// user_id
							flag = preparedStatement.executeUpdate();//执行查询语句
							//System.out.println("修改用户余额，是否成功：" + flag);

							queryString = "update ft_taobaoNumber set status=? where number=?";//问号作为参数的占位符
							preparedStatement = conn.prepareStatement(queryString);
							preparedStatement.setDouble(1, 1);		// status
							preparedStatement.setString(2, row[0]);	// 淘宝交易编号
							flag = preparedStatement.executeUpdate();//执行查询语句
							//System.out.println("修改交易号为已使用，是否成功：" + flag);



							HttpUtil hu = new HttpUtil();
							hu.sendGet(pageHome + "/api/topUpController/autoTopUpCallBack", "account=" + user.getAccount(), "utf-8");

							hu = null;
							id = null;
							balanceNext = null;
							topUpProportion = null;
						}

						queryString = null;
					}


				}
				sql = null;
				user = null;


			}

			// 加上一个回车
			System.out.println();

			if (StringUtil.isNotEmpty(resultSet))
				resultSet.close();
			if (StringUtil.isNotEmpty(conn))
				conn.close();
			if (StringUtil.isNotEmpty(preparedStatement))
				preparedStatement.close();




		} catch (SQLException ex) {
			ex.printStackTrace();
		} finally {
			try{
				if (StringUtil.isNotEmpty(resultSet))
					resultSet.close();
				if (StringUtil.isNotEmpty(conn))
					conn.close();
				if (StringUtil.isNotEmpty(preparedStatement))
					preparedStatement.close();
			} catch (Exception e){
				e.printStackTrace();
			}
		}

		toDayTransactionNumberStr = null;
		ToDay_Number = null;

		webEngine.executeScript("setTimeout(function(){location.reload()},1000*10)");
		System.gc();

		Worker<Void> worker = webEngine.getLoadWorker();
		ReadOnlyObjectProperty<Worker.State> objectProperty = worker.stateProperty();
		objectProperty.removeListener(this);
		objectProperty.addListener(this);
	}

	private Connection initializeDB() {
		Connection conn = null;
		try {

			ResourceBundle resource = ResourceBundle.getBundle("db");

			Class.forName(resource.getString("jdbc.driver"));

			String url = resource.getString("jdbc.url");
			String username = resource.getString("jdbc.username");
			String password = resource.getString("jdbc.password");

			pageHome = resource.getString("pageHome");
			conn = DriverManager.getConnection(url, username, password);
			//System.out.println("Database connected");


		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return conn;
	}
}
